import type { BusinessUIQueryColumnType, DicType, FormComponentType } from '@/types/custom'
import { isObject } from '@vueuse/core'
import {
  clone,
  eachTree,
  findTree,
  isArray,
  orderBy,
  toArrayTree,
  type ToArrayTreeOptions
} from 'xe-utils'
import { formComponents } from '@/utils/custom'
import { useBaseApi } from '@/api/base'
import { useWfApi } from '@/api/wf'

const { GetWorkFlowDesignInsNames } = useWfApi()
const { search_all_users, CustomRequest } = useBaseApi()

// StateInterface
export interface StateInterface {
  [key: string]: SelectOptionType[]
}

/**
 * 查询流程实体
 * @param list 表单组件数据
 * @param params 表单数据
 */
export const onFetchIns = async (list: BusinessUIQueryColumnType[], params: TypedAny) => {
  const { data } = await GetWorkFlowDesignInsNames(params)
  const items: SelectOptionType[] = []
  for (const k in data) {
    items.push({ value: k, label: data[k] })
  }
  return items
}

/**
 * 获取所有用户
 * @param list 表单组件数据
 * @param params 表单数据
 */
export const onFetchUser = async (list: BusinessUIQueryColumnType[], params: TypedAny) => {
  const { data } = await search_all_users({
    status_dis: 0,
    status_leave: 0,
    ...params
  })
  const { deps, users } = data
  users.forEach((user) => {
    user.value = user.id
    user.label = user.name
  })
  deps.forEach((dep) => {
    const items = users.filter((user) => user['dep_id'] === dep.id)
    dep.value = dep.id
    dep.label = `${dep.name}[${items.length}人]`
    dep.disabled = !deps.some((s) => s.pid === dep.id) && !items.length
    items.forEach((user) => {
      user.pid = dep.id
    })
  })
  return toArrayTree(deps.concat(users), { parentKey: 'pid', sortKey: 'sort' })
}

/**
 * 获取所有联动的参数
 * @param items 表单组件数据
 * @param params 表单数据
 */
export const getLinkageParams = (items: BusinessUIQueryColumnType[], params: TypedAny) => {
  const option: TypedAny = {}
  // 需要调用接口的列
  const apis = items.filter((f) => f.is_api)
  apis.forEach((item) => {
    // 默认参数
    const default_value_parse = item.default_value_parse
    if (default_value_parse) {
      for (const k in default_value_parse) {
        const value = params[k]
        if (value !== undefined) option[k] = value
      }
    }
  })

  // 联动的列
  const linkages = items.filter((f) => f.set_json_parse.linkage)
  linkages.forEach((item) => {
    const value = params[item.field]
    // 原始参数
    if (value !== undefined && value !== null) {
      option[item.field] = value
    }
  })

  // 重命名
  const converts = items.filter(
    (f) => Object.values(f.set_json_parse.convert || {}).filter((f) => f).length
  )
  converts.forEach((item) => {
    const set_json_parse = item.set_json_parse || {}
    const convert = set_json_parse.convert
    if (convert) {
      for (const k in convert) {
        if (convert[k]) option[convert[k]] = option[k]
      }
    }
  })

  return option
}

/**
 * 获取所有列的字典下拉
 * @param items 表单列
 * @param state 数据对象
 * @param dicTable 字典集合
 */
export const onInitDicData = (
  items: BusinessUIQueryColumnType[],
  state: StateInterface,
  dicTable?: DicType[]
) => {
  const dicItems = dicTable || []
  const list = items.filter((f) => ['el-select'].includes(f.component) && !f.is_api)
  list.forEach((v) => {
    const dics = dicItems.filter((f) => f.column_name === v.field)
    state[v.field] = dics.map((v) => {
      return {
        value: v.value_text,
        label: v.display_text
      }
    })
  })
}

/**
 * 表单联动后提示信息的请求
 * @param items 表单组件数据
 * @param params 传递父级参数或者其他参数
 * @param formParams 表单数据
 * @param state 下拉数据集合
 */
export const onInitApiData = async (
  items: BusinessUIQueryColumnType[],
  state: StateInterface,
  params: TypedAny,
  formParams: TypedAny
) => {
  // if (Object.keys(params).length) {
  const notComponent = ['el-cascader']
  const api_items = items.filter((f) => {
    return f.is_api && f.set_json_parse.url && !notComponent.includes(f.elComponent || '')
  })
  for (const item of api_items) {
    const { data } = await CustomRequest({
      url: item.set_json_parse.url,
      method: item.set_json_parse.method,
      params: item.set_json_parse.method === 'get' ? params : {},
      data: item.set_json_parse.method === 'post' ? params : {}
    })
    if (['api-select', 'api-tree-select'].includes(item.component)) {
      const list = data.map((v: TypedAny) => {
        return {
          value: v.id,
          label: v.name,
          pid: v.pid,
          sort: v.idx === undefined ? v.sort : v.idx
        }
      })
      const option: ToArrayTreeOptions<any> = { parentKey: 'pid', key: 'value', sortKey: 'sort' }
      if (item.component === 'api-tree-select') {
        state[item.field] = toArrayTree(list, option)
      } else {
        state[item.field] = list
      }
    } else if (isObject(data)) {
      let description = ''
      const option: TypedAny = data
      for (const k in option) {
        description += `${k}: ${option[k] || ''}；`
      }
      formParams[item.field] = description
    } else {
      formParams[item.field] = data
    }
  }
  // }
}

/**
 * 根据组件配置的接口地址请求下拉数据
 * @param items 表单组件数据
 * @param state 下拉数据集合
 * @param params 传递父级参数或者其他参数
 * @param formParams 表单数据
 */
export const onComponentServerFetch = async (
  items: BusinessUIQueryColumnType[],
  state: StateInterface,
  params: TypedAny,
  formParams: TypedAny
) => {
  const apis: FormComponentType[] = []
  eachTree(formComponents, (data) => {
    const cloneData = clone(data, true)
    const list = items.filter((f) => f.component === cloneData.value)
    list.forEach((item) => {
      if (!apis.some((s) => s.value === item.component) && cloneData.server) {
        const set_json_parse = item.set_json_parse || {}
        const convert = set_json_parse.convert
        if (convert) {
          const params = cloneData.server.params || {}
          for (const k in convert) {
            if (convert[k]) params[convert[k]] = params[k]
          }
          cloneData.server.params = params
          cloneData.field = item.field
        }
        apis.push(cloneData)
      }
    })
  })
  // 动态数据
  for (const v of apis) {
    const server = v.server || { api: '', method: '', value: 'id', label: 'name' }
    const assignParams = Object.assign(clone(server.params || {}, true), params)
    const labelSplit = server.label.split(',')
    const { data } = await CustomRequest({
      url: server.api,
      method: server.method,
      params: server.method === 'get' ? assignParams : {},
      data: server.method === 'post' ? assignParams : {}
    })
    const items: SelectOptionType[] = []
    data.forEach((v: any) => {
      const option = {
        value: v[server.value] || '',
        label: labelSplit.map((k) => v[k]).join('-'),
        pid: server.pid ? v[server.pid] : undefined,
        sort: server.sort ? v[server.sort] : undefined
      }
      items.push(option)
    })
    const value = formParams[String(v.field)]
    const sortKey = server.sort
    if (server.pid) {
      const option: ToArrayTreeOptions<any> = { parentKey: 'pid', key: 'value' }
      if (sortKey) {
        option.sortKey = sortKey
      }
      state[v.value] = toArrayTree(items, option)
      if (isArray(value) && value.length) {
        formParams[String(v.field)] = value.filter((id) => {
          const item = findTree(state[v.value], (f) => f.value === id)
          return item && item.item
        })
      } else if (value) {
        const item = findTree(state[v.value], (f) => f.value === value)
        if (!item || !item.item) {
          formParams[String(v.field)] = undefined
        }
      }
    } else {
      if (sortKey) {
        state[v.value] = orderBy(items, sortKey)
      } else {
        state[v.value] = items
      }
      if (isArray(value) && value.length) {
        formParams[String(v.field)] = value.filter((id) =>
          state[v.value].some((s) => s.value === id)
        )
      } else if (value) {
        if (!state[v.value].some((s) => s.value === value)) {
          formParams[String(v.field)] = undefined
        }
      }
    }
  }
}

/**
 * 设置默认参数
 * @param items 表单组件数据
 * @param params 表单数据
 * @param isNotToString 为true时转成空字符串，否则undefined
 */
export const setFormDefaultParams = (
  items: BusinessUIQueryColumnType[],
  params: TypedAny,
  isNotToString?: boolean
) => {
  items.forEach((v) => {
    const item = findTree(formComponents, (item) => item.value === v.component)
    if (item && item.item) {
      if (
        v.set_json_parse.props.multiple === 'true' ||
        v.set_json_parse.props.type === 'daterange'
      ) {
        params[v.field] = []
      } else if (item.item.type === 'array') {
        if (v.set_json_parse.props.multiple === 'true') {
          params[v.field] = []
        } else {
          params[v.field] = isNotToString ? '' : undefined
        }
      } else if (item.item.type === 'number') {
        params[v.field] = 0
      } else {
        params[v.field] = isNotToString ? '' : undefined
      }
    }
  })
  return params
}

/**
 * 是否显示列
 * @param form
 * @param params
 */
export const isShowCol = (form: BusinessUIQueryColumnType, params: TypedAny) => {
  const isComponent = !!form.component
  const isText = [
    'custom-pre',
    'custom-json',
    'custom-title',
    'el-text',
    'custom-annex',
    'custom-image'
  ].includes(form.component)
  const isValue = !!params[form.field]
  const isTextAndValue = isText ? isValue : true
  return isComponent && (form.title || isTextAndValue || form.set_json_parse.description)
}

/**
 * 获取显示name
 * @param form
 * @param formatParams
 * @param formParams
 */
export const getRelName = (
  form: BusinessUIQueryColumnType,
  formatParams: TypedAny = {},
  formParams: TypedAny
) => {
  const _name = `${form.field}_name`
  const value = formatParams[_name] || formParams[_name]
  if (value) {
    return value
  } else if (form.rel_item) {
    return (
      formatParams[form.rel_item] ||
      formatParams[form.field] ||
      form.set_json_parse.description ||
      '--'
    )
  } else {
    return (
      formatParams[form.field] || formParams[form.field] || form.set_json_parse.description || '--'
    )
  }
}
